from urllib import parse as urllib_parse
import requests

from core import errors


class KunyuanClient:
    def __init__(self, endpoint_url: str, auth_username: str, auth_password: str):
        self.endpoint_url = endpoint_url
        self.auth_username = auth_username
        self.auth_password = auth_password

    @staticmethod
    def enforce_query(query):
        """
        强制为query字符串

        :param query: None or str or dict
        :return:
            str
        """
        if isinstance(query, dict):
            query_str = urllib_parse.urlencode(sorted(list(query.items())), doseq=True)
        elif isinstance(query, str):
            query_str = query
        else:
            query_str = ''

        return query_str

    @staticmethod
    def build_url(endpoint_url: str, path: str, query=None, fragment: str = '', trailing_slash=False):
        """
        构建url

        :param endpoint_url:
        :param path:
        :param query: type: str or dict;
        :param fragment:
        :param trailing_slash: 默认False，path后不尾随/；
        :return:
        """
        query_str = KunyuanClient.enforce_query(query)

        if trailing_slash and not path.endswith('/'):
            path += '/'
        elif not trailing_slash and path.endswith('/'):
            path = path.rstrip('/')

        endpoint_url = endpoint_url
        scheme, netloc, _, _, _ = urllib_parse.urlsplit(endpoint_url)
        return urllib_parse.urlunsplit((scheme, netloc, path, query_str, fragment))

    @staticmethod
    def build_error_form_response(response: requests.Response) -> errors.Error:
        try:
            data = response.json()
            message = f"{data['code']}，{data['message']}"
        except Exception:
            message = response.text

        return errors.Error(message=message)

    def add_admins_to_kunyuan(self, usernames: list[str]):
        """
        同步云节点管理员权限到中坤服务

        :raises: Error
        """
        try:
            api_url = self.build_url(self.endpoint_url, path='/api/app_users/admin/add')
            r = requests.post(
                url=api_url, data={'usernames': usernames},
                auth=(self.auth_username, self.auth_password),
                timeout=(6, 10))
            if r.status_code == 200:
                return True
        except Exception as e:
            raise errors.Error(message=str(e))

        raise self.build_error_form_response(response=r)

    def remove_admins_from_kunyuan(self, usernames: list[str]):
        """
        从中坤服务移除云节点管理员权限

        :raises: Error
        """
        try:
            api_url = self.build_url(self.endpoint_url, path='/api/app_users/admin/remove')
            r = requests.post(
                url=api_url, data={'usernames': usernames},
                auth=(self.auth_username, self.auth_password),
                timeout=(6, 10))
            if r.status_code == 200:
                return True
        except Exception as e:
            raise errors.Error(message=str(e))

        raise self.build_error_form_response(response=r)

    def get_kunyuan_version(self) -> str:
        try:
            api_url = self.build_url(self.endpoint_url, path='/api/version')
            r = requests.get(url=api_url, timeout=(6, 10))
            if r.status_code == 200:
                data = r.json()
                version = data['version']
                return version
        except Exception as e:
            raise errors.Error(message=str(e))

        raise self.build_error_form_response(response=r)


